import os
import ConfigParser
import sys
try:
	import pygame
	from pygame.locals import * 
except ImportError,e:
	print "Can't find pygame. Please download and install pygame from http://www.pygame.org";
	sys.exit(1)
	
class Factory:
    def CanHandle(self,path):
        return False
    def Build(self,resId):
        """Load the ressource ndreturn a pointer to the built object"""        
        return None
        
class UnhandeledError(Exception):
    """To throw when a factory can't handle the ressource"""
    pass

class FontFactory(Factory):
    def CanHandle(self,path):        
        formats=["TTF"]
        s=path.split(":")
        ext=os.path.splitext(s[0])[1].strip(".").upper()
        return ext in formats        
    def Build(self,path):
        if not self.CanHandle(path): raise UnhandeledError()
        s=path.split(":")        
        return pygame.font.Font(s[0],int(s[1]))
    
class SoundFactory(Factory):
    def CanHandle(self,path):        
        formats=["VOC"]        
        ext=os.path.splitext(path)[1].strip(".").upper()
        return ext in formats        
    def Build(self,path):
        if not self.CanHandle(path): raise UnhandeledError()        
        if not pygame.mixer.get_init():
            #sound seems to be disabled
            return None
        return pygame.mixer.Sound(path)
        
    
class MidiFactory(Factory):
    def CanHandle(self,path):        
        formats=["MID"]        
        ext=os.path.splitext(path)[1].strip(".").upper()
        return ext in formats        
    def Build(self,path):
        if not self.CanHandle(path): raise UnhandeledError()        
        if not pygame.mixer.get_init():
            #sound seems to be disabled
            return None
        return path
     
class ImageFactory(Factory):
    def CanHandle(self,path):
        if pygame.image.get_extended():
            formats=["JPG","PNG","GIF","BMP","PCX","TGA","TIF","LBM","PBM","XPM"];
        else:
            formats=["BMP","TGA","PNG","JPG"];
        s=path.split(":")
        if not len(s)in [1,2,3]:
            return False
        ext=os.path.splitext(s[0])[1].strip(".").upper()
        return ext in formats
    
    def Build(self,path):
        if not self.CanHandle(path): raise UnhandeledError()
        s=path.split(":")
        
        surf=pygame.image.load(s[0])
        if len(s)==3:
            surf=pygame.transform.rotate(surf, float(s[2]))            
        if len(s)>=2:
            w=int(surf.get_width() *float(s[1]))
            h=int(surf.get_height()*float(s[1]))
            surf=pygame.transform.scale(surf,(w,h))
        return surf
        
        
class ConfigFactory(Factory):
    def CanHandle(self,path): 
        formats=["INI", "CFG"]
        ext=os.path.splitext(path)[1].strip(".").upper()
        return ext in formats        
    def Build(self,path):
        if not self.CanHandle(path): raise UnhandeledError()        
        config = ConfigParser.ConfigParser()
        config.readfp(open(path))
        return config

class ResLoadFailed(Exception):
    def __init__(self, resId):
        self.resId = resId
    def __str__(self):
        return repr(self.resId)

        
class ResourceManager:
    def __init__(self):
        self.available={} #tie id to object instances
        self.factories=[ImageFactory(), ConfigFactory(),FontFactory(),SoundFactory(),MidiFactory()] #is able to build the object
        self.root="res"
    
    def Load(self, resId):
        if resId in self.available:    return self.available[resId]
        path=os.path.join(self.root, resId)
        for f in self.factories:
            if f.CanHandle(path):                                
                r=self.available[resId]=f.Build(path)
                return r
        raise ResLoadFailed(resId)